﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BPTrigger
{
	public enum BPTriggerType
	{
		None = 0,		
		Always = 1,			//一直执行
		TimeAbout = 2,		//与游戏进程时间相关
		SceneAbout = 3,		//与游戏场景事件相关
		PlayerCountAbout = 4,    //与玩家个数相关
		AreaAbout = 5,		//与某一区域相关
	}
	public enum BPTriggerStatus
	{
		None = 0,
		Listening = 1,
		Execute = 2,
		Closed = 3
	}

	protected BattleProcessManager Parent { get; set; }
	protected float AccuracyRate { get; set; } = 0.02f;
	protected bool SceneEventTriggerSuccess = false;
	protected BPInstructionSet instructionSet;
	protected float lastTime = 0;

	public BPTriggerStatus BPTStatus { get; protected set; } = BPTriggerStatus.None;
	public bool IsTriggered => (BPTStatus == BPTriggerStatus.Execute) || (BPTStatus == BPTriggerStatus.Closed);
	public BPTriggerType BPTType { get; set; } = BPTriggerType.SceneAbout;

	#region Trigger Listening Param
	public string TriggerName;

	public int SceneEvent { get; set; } = (int)global::SceneEvent.EVENT_SCENE_START;
	public int Scene { get; set; } = (int)global::Scene.BattleScene;

	public int PlayerMinCount { get; set; } = 0;
	public int PlayerMaxCount { get; set; } = 999;

	public string ParamString;
	#endregion


	virtual public void Init(BattleProcessManager parent, BPInstructionSet set)
	{
		this.Parent = parent;
		this.instructionSet = set;
		SceneEventTriggerSuccess = false;
		//Do Listening Trigger
		_ChangeStatus(BPTriggerStatus.Listening);
	}

	virtual public void DoUpdate(float deltaTime)
	{
		if(this.BPTStatus == BPTriggerStatus.Listening)
		{
			_UpdateListen(deltaTime);
		}
		else if(this.BPTStatus == BPTriggerStatus.Execute)
		{
			_UpdateExecute(deltaTime);
		}
	}
	
	/// <summary>
	/// SceneEvent Trigger Status Change
	/// </summary>
	/// <param name="ev"></param>
	/// <param name="evp"></param>
	virtual public void ReceiveSceneEvent(int ev, int evp)
	{
		if (this.BPTType == BPTriggerType.SceneAbout)
		{
			if(ev == SceneEvent && evp == Scene)
			{
				SceneEventTriggerSuccess = true;
			}
		}
	}

	/// <summary>
	/// PlayerCountAbout Trigger Status Change
	/// </summary>
	virtual public bool CheckPlayerCount()
	{
		if(this.BPTType == BPTriggerType.PlayerCountAbout)
		{
			//int current = BattleLogic.Instance.PlayerCount;
			int current = GamePlayFacade.Instance.Sub_Battle.PlayerCount;
			if (current <= PlayerMinCount || current >= PlayerMaxCount)
			{
				return true;
			}
		}
		return false;
	}


	public void ChangeStatus(BPTriggerStatus status)
	{
		_ChangeStatus(status);
	}

	public void Disable()
	{
		if (this.BPTStatus != BPTriggerStatus.None || this.BPTStatus != BPTriggerStatus.Closed)
		{
			if (this.BPTStatus == BPTriggerStatus.Listening)
				_ChangeStatus(BPTriggerStatus.None);
			else if (this.BPTStatus == BPTriggerStatus.Execute)
				_ChangeStatus(BPTriggerStatus.Closed);
		}
	}

	public void Enable()
	{
		if (this.BPTStatus == BPTriggerStatus.None)
			_ChangeStatus(BPTriggerStatus.Listening);
	}

	virtual protected void _ChangeStatus(BPTriggerStatus status)
	{
		this.BPTStatus = status;
		if(this.BPTStatus == BPTriggerStatus.Execute)
		{
			//从头执行指令集
			//TODO 
			if (null == instructionSet)
				return;
			instructionSet.DoStart(this);
			instructionSet.DoUpdate(0);
		}
	}
	virtual protected void _UpdateListen(float deltaTime)
	{
		lastTime += deltaTime;
		if (lastTime < AccuracyRate)
			return;
		lastTime = 0;
		switch (BPTType)
		{
			case BPTriggerType.Always:
				_TriggerSuccess();
				break;
			case BPTriggerType.SceneAbout:
				if (SceneEventTriggerSuccess)
				{
					SceneEventTriggerSuccess = false;
					_TriggerSuccess();
				}
				break;
			case BPTriggerType.TimeAbout:
				break;
			case BPTriggerType.PlayerCountAbout:
				if(CheckPlayerCount())
					_TriggerSuccess();
				break;
			case BPTriggerType.AreaAbout:
				break;

		}
	}
	virtual protected void _UpdateExecute(float deltaTime)
	{
		if (null != instructionSet)
		{
			instructionSet.DoUpdate(deltaTime);
		}
		//Debug.Log("");
		if (null != instructionSet)
		{
			if (instructionSet.IsAbort)
				return;
			else if (instructionSet.IsEnd)
			{
				_ChangeStatus(BPTriggerStatus.Closed);
			}
		}
	}

	protected void _TriggerSuccess()
	{
		_ChangeStatus(BPTriggerStatus.Execute);
	}
}
